package com.flatsmap.dao;

import static com.flatsmap.util.FlatsMapUtil.createMinMaxCriteria;
import static com.flatsmap.util.FlatsMapUtil.isEmpty;
import static com.flatsmap.util.FlatsMapUtil.isNotEmpty;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.criterion.Property;

import com.flatsmap.dto.PoiDTO;
import com.flatsmap.dto.SearchCriteria;

public class PoiDao extends AbstractDao<PoiDTO> {

	@Override
	public Class getClazz() {
		return PoiDTO.class;
	}

	public SearchCriteria getMinMaxValues(){
		PoiDTO min = (PoiDTO)getSession().createSQLQuery(
				"select min(price) {p.price}, min(floor) {p.floor}, min(room_number) {p.roomNumber}, min(square) {p.square} " +
				" 0 {p.id}, '' {p.address}, '' {p.description}, " +
				" '' {p.region}, '' {p.city}, '' {p.contacts}, '' {p.street} " +
				" 0.0 {p.lat}, 0.0 {p.lng} " +
				" from pois p")
				.addEntity("p", PoiDTO.class)
				.setMaxResults(1).uniqueResult();
		PoiDTO max = (PoiDTO)getSession().createSQLQuery(
				"select max(price) {p.price}, max(floor) {p.floor}, max(room_number) {p.roomNumber}, max(square) {p.square} " +
				" 0 {p.id}, '' {p.address}, '' {p.description}, " +
				" '' {p.region}, '' {p.city}, '' {p.contacts}, '' {p.street} " +
				" 0.0 {p.lat}, 0.0 {p.lng} " +
				" from pois p")
				.addEntity("p", PoiDTO.class)
				.setMaxResults(1).uniqueResult();
		
		return createMinMaxCriteria(min, max);
	}

	public List<PoiDTO> getPois(SearchCriteria criteria){
		Criteria c =  getSession()
		.createCriteria(getClazz());
		
		if(isEmpty(criteria))
			return new ArrayList<PoiDTO>();
		
		if(isNotEmpty(criteria.getRegion())){
			c.add(Property.forName("region").eq(criteria.getRegion()));
		}
		if(isNotEmpty(criteria.getStreet())){
			c.add(Property.forName("street").eq(criteria.getStreet()));
		}
		if(isNotEmpty(criteria.getCity())){
			c.add(Property.forName("city").eq(criteria.getCity()));
		}
		if(isNotEmpty(criteria.getMaxFloor())){
			c.add(Property.forName("floor").le(criteria.getMaxFloor()));
		}
		if(isNotEmpty(criteria.getMinFloor())){
			c.add(Property.forName("floor").ge(criteria.getMinFloor()));
		}
		if(isNotEmpty(criteria.getMaxRoomNumber())){
			c.add(Property.forName("roomNumber").le(criteria.getMaxRoomNumber()));
		}
		if(isNotEmpty(criteria.getMinRoomNumber())){
			c.add(Property.forName("roomNumber").ge(criteria.getMinRoomNumber()));
		}
		if(isNotEmpty(criteria.getMaxPrice())){
			c.add(Property.forName("price").le(criteria.getMaxPrice()));
		}
		if(isNotEmpty(criteria.getMinPrice())){
			c.add(Property.forName("price").ge(criteria.getMinPrice()));
		}
		if(isNotEmpty(criteria.getMaxSquare())){
			c.add(Property.forName("square").le(criteria.getMaxSquare()));
		}
		if(isNotEmpty(criteria.getMinSquare())){
			c.add(Property.forName("square").ge(criteria.getMinSquare()));
		}
		
		return c.list();
	}

}
